package org.gas.barapraja.proc;

import java.io.IOException;

import com.logica.smpp.Connection;
import com.logica.smpp.Data;
import com.logica.smpp.TCPIPConnection;

public class GasSmscListener implements Runnable{
	
	private Connection connection;
	private int port;
	private long acceptTimeout=Data.ACCEPT_TIMEOUT;
	private boolean keepReceiving = true;
    private boolean isReceiving = false;
    private boolean asynchronous = false;
    private ProcessorFactory processorFactory;

	/**
	 * @param port
	 */
	public GasSmscListener(int port) {
		super();
		this.port = port;
	}


	/**
	 * @param port
	 * @param asynchronous
	 */
	public GasSmscListener(int port, boolean asynchronous) {
		super();
		this.port = port;
		this.asynchronous = asynchronous;
	}


	public synchronized void start() throws IOException{
		if(!isReceiving){
			connection=new TCPIPConnection(port);
			connection.setReceiveTimeout(getAcceptTimeout());
			connection.open();
			if(asynchronous){
				Thread server=new Thread(this);
				server.start();
			}else{
				run();
			}
		}else{
			
		}
	}
	
	public synchronized void stop() throws IOException{
		keepReceiving = false;
        while (isReceiving) {
            Thread.yield();
        }
        connection.close();
       
	}
	
	void listen(){
		Connection conn=null;
		connection.setReceiveTimeout(getAcceptTimeout());
		try {
			conn=connection.accept();
			if(conn!=null){
				GasSmscSession session=new GasSmscSession(conn);
				PduProcessor pduProcessor=null;
				if(processorFactory!=null){
					pduProcessor=processorFactory.createIncomingProcessor(session);
				}
				if(!session.getPduProcessor().equals(pduProcessor))
					session.setPduProcessor(pduProcessor);
				Thread serverThread=new Thread(session);
				serverThread.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	public void run() {
		 isReceiving = true;
	        try {
	            while (keepReceiving) {
	                listen();
	                Thread.yield();
	            }
	        } finally {
	            isReceiving = false;
	        }
		
	}


	public ProcessorFactory getProcessorFactory() {
		return processorFactory;
	}


	public void setProcessorFactory(ProcessorFactory processorFactory) {
		this.processorFactory = processorFactory;
	}


	public long getAcceptTimeout() {
		return acceptTimeout;
	}

	
}
